package net.helix.engine.timeline;

import java.util.ArrayList;

import net.helix.core.transform.TransformDimension;
import net.helix.element.Element;
import net.helix.engine.timeline.frame.TimelineFrame;
import net.helix.engine.timeline.frame.TimelineKeyFrame;
import net.helix.engine.timeline.layer.TimelineLayer;
import net.helix.engine.timeline.layer.TimelineLayerType;

public class Timeline {
	public ArrayList<TimelineLayer> layers;
	
	
	/** The last layer that was selected... When an item is dragged from the library, it is placed into this layer */
	private TimelineLayer currentSelectedLayer = null;
	
	public Timeline(boolean fill){
		layers = new ArrayList<TimelineLayer>();
		if(fill){
			addNewLayerTo(addNewLayer(true, TimelineLayerType.CAMERA, TransformDimension.THREE), true, TimelineLayerType.NORMAL, TransformDimension.THREE);
			addNewLayerTo(addNewLayer(true, TimelineLayerType.CAMERA, TransformDimension.TWO), true, TimelineLayerType.NORMAL, TransformDimension.TWO);
		}
	}
	static int layerNumberCount = 0;
	static int cameraNumberCount = 0;
	public TimelineLayer MakeNewLayer(boolean fill, TimelineLayerType type, TransformDimension dimension){
		// TODO: check names of all existing layers so that two names aren't the
		// same on accident.
		String name = "";
		if(type == TimelineLayerType.CAMERA){
			name = "Camera "+(++cameraNumberCount);
		}else{
			name = "Layer "+(++layerNumberCount);
		}
		TimelineLayer r = new TimelineLayer(this, fill, name, type, dimension);
		return r;
	}
	public void addLayerToEnd(TimelineLayer layer){
		layers.add(layer);
	}
	public void addLayerBefore(TimelineLayer layer, TimelineLayer before){
		for(int i=0;i<layers.size();i++){
			TimelineLayer checkLayer = layers.get(i);
			if(checkLayer == before){
				layers.add(i, layer);
				return;
			}
		}
		throw new Error("Error: addLayerBefore, was not in list");
	}
	public void addLayerAfter(TimelineLayer layer, TimelineLayer after){
		for(int i=0;i<layers.size();i++){
			TimelineLayer checkLayer = layers.get(i);
			if(checkLayer == after){
				layers.add(i+1, layer);
				return;
			}
		}
		throw new Error("Error: addLayerAfter, was not in list");
	}
	public TimelineLayer addNewLayer(boolean fill, TimelineLayerType type, TransformDimension dimension){
		TimelineLayer r = MakeNewLayer(fill, type, dimension);
		layers.add(r);
		return r;
	}
	public TimelineLayer addNewLayerTo(TimelineLayer layer, boolean fill, TimelineLayerType type, TransformDimension dimension){
		if(layer.type == TimelineLayerType.FOLDER || layer.type == TimelineLayerType.CAMERA){
			TimelineLayer r = MakeNewLayer(fill, type, dimension);
			
			layer.AddChildLayer(r);
			
			return r;
		}else{
			throw new Error("Error: AddNewLayerTo");
		}
	}
	/*
	public void addElement(Element element, TimelineLayer layer, float frame){
		// TODO: make sure selected layer is in this timeline
		if(layer != null){
			// TODO: check if frame exists...
			System.out.println("adding element to frame "+frame + " in layer "+layer.name);
			TimelineFrame theFrame = layer.frames.get((int) frame);
			if(theFrame != null){
				if(theFrame instanceof TimelineKeyFrame){
					((TimelineKeyFrame) theFrame).AddElement(element, layer.dimension);
				}else{
					// TODO: get closest keyFrame to the left, then add to that.
				}
			}else{
				System.out.println("frame " + frame + " is null");
				
			}
		}else{
			// TODO: make it do something
		}
	}
	*/
	public void removeLayer(TimelineLayer layer){
		layers.remove(layer);
	}
	
	/**
	 * Renders everything in this timeline at this frame.
	 */
	public void renderAtFrame(float frame){
		for(int i=layers.size()-1; i>=0;i--){
			TimelineLayer layer = layers.get(i);
			layer.renderAtFrame(frame);
		}
	}
	
	/**
	 * Set the current layer selected inside the current timeline.
	 * @param layer
	 */
	public void setCurrentSelectedLayer(TimelineLayer layer){
		// TODO: Assert that the layer exists inside the currentSelectedTimeline
		currentSelectedLayer = layer;
	}
	
	/**
	 * Get the current selected layer.
	 * @return
	 */
	public TimelineLayer getCurrentSelectedLayer(){
		return currentSelectedLayer;
	}
	
	
}
